package com.rimi.config;

import com.rimi.shiro.AnyRolesAuthorizationFilter;
import com.rimi.shiro.BearerFilter;
import com.rimi.shiro.BearerRealm;
import com.rimi.shiro.MysqlRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.mgt.SubjectDAO;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.*;

/**
 * @author 罗晨
 * @version V1.0
 * @Description: 用一句话描述该文件做什么
 * @date 2021 2021/6/30 14:42
 */
@Configuration
public class ShiroConfig {

    @Autowired(required = false)
    SubjectDAO subjectDAO;

    /**
     * 开启动态代理注解扫描
     * @return
     */

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }


    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        //创建过滤器工厂
        ShiroFilterFactoryBean filterFactoryBean=new ShiroFilterFactoryBean();
        //登录界面的地址
        filterFactoryBean.setLoginUrl("/login");
        //成功登陆界面的地址
        //filterFactoryBean.setSuccessUrl();

        //角色权限效验失败的地址
        //filterFactoryBean.setUnauthorizedUrl("/401.html");

        //使用哪种安全管理器
        filterFactoryBean.setSecurityManager(securityManager());
        //使用的全局过滤器集合
        //filterFactoryBean.setGlobalFilters();

        //创建过滤规则(有先后顺序),从上到下进行匹配，以第一个匹配到的规则为准
//        Map<String,String> define=new LinkedHashMap<>();
//
//         //必须进行身份效验
//        define.put("/user/**","authc");
//        //所有的url都不进行效验
//        define.put("/**","anon");

        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append("/user/**=authcBearer");
        stringBuilder.append("\n");
        stringBuilder.append("\n");
        stringBuilder.append("/**=anon");


        stringBuilder.append("\n");
        //使用的自定义过滤器规则
        //filterFactoryBean.setFilterChainDefinitionMap(define);


        filterFactoryBean.setFilterChainDefinitions(stringBuilder.toString());

        //自定义的shiro内置过滤器
        //filterFactoryBean.setFilters();

        Map<String, Filter> filterMap=new HashMap<>();
        //给过滤器起一个名字，交给shiro管理
        filterMap.put("roles",new AnyRolesAuthorizationFilter());
        filterMap.put("authcBearer",new BearerFilter());
        filterFactoryBean.setFilters(filterMap);

        return filterFactoryBean;
    }

    @Bean
    public SessionsSecurityManager securityManager(){
        //创建安全管理器
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();

        //设置身份认证和权限效验的认证方式
        List<Realm> mysqlRealms = Arrays.asList(mysqlRealm(),bearerRealm());
        securityManager.setRealms(mysqlRealms);

        // 关闭session存储
        DefaultSubjectDAO defaultSubjectDAO = (DefaultSubjectDAO)subjectDAO;
        DefaultSessionStorageEvaluator sessionStorageEvaluator = (DefaultSessionStorageEvaluator) defaultSubjectDAO.getSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        securityManager.setSubjectDAO(subjectDAO);


        return securityManager;
    }


    //设置身份认证和权限效验的认证方式
    @Bean
    public MysqlRealm mysqlRealm(){

        MysqlRealm mysqlRealm = new MysqlRealm();
        //摄者数据库密码比较器
        mysqlRealm.setCredentialsMatcher(credentialsMatcher());

        return mysqlRealm;
    }

    // 设置身份认证和权限效验的认证方式
    @Bean
    public BearerRealm bearerRealm(){

        BearerRealm bearerRealm=new BearerRealm();
        //摄者数据库密码比较器
//        bearerRealm.setCredentialsMatcher(credentialsMatcher());

        return bearerRealm;
    }



    public HashedCredentialsMatcher credentialsMatcher(){
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        //采用哪种hash算法进行加密
        matcher.setHashAlgorithmName("md5");

        //加密次数
        matcher.setHashIterations(10);

        return matcher;


    }
}
